#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
线程类 - PySide6版本
对应原C++项目的多线程架构
"""

import cv2
import numpy as np
import threading
import time
from PySide6.QtCore import QThread, Signal, Slot, QMutex, QMutexLocker
from PySide6.QtWidgets import QApplication


class SendImage:
    """图像发送类 - 对应C++的SendImage"""

    def __init__(self):
        self.capture = None
        self.img_vector = []
        self.img1 = None
        self.img2 = None
        self.img3 = None
        self.img4 = None
        self.mutex = QMutex()
        self.img_count = 0

    def push_img(self):
        """推送图像到队列"""
        self.mutex.lock()
        try:
            if self.capture is not None:
                # 创建图像的副本用于处理
                self.img1 = self.capture.copy()
                # 这里简化处理，实际应该有更复杂的图像处理逻辑
                self.img2 = self.img1.copy()
                self.img3 = self.img2.copy()
                self.img4 = self.img3.copy()
                self.img_count += 1
        finally:
            self.mutex.unlock()

    def pop_img(self):
        """从队列弹出图像"""
        self.mutex.lock()
        try:
            if self.img_count > 0:
                self.img_count -= 1
                return True
            return False
        finally:
            self.mutex.unlock()

    def get_img_cnt(self):
        """获取图像计数"""
        self.mutex.lock()
        try:
            return self.img_count
        finally:
            self.mutex.unlock()


class EventThread(QThread):
    """事件线程 - 对应C++的event_thread"""

    # 定义信号
    sig_get_nms = Signal()

    def __init__(self, xdma_driver):
        super().__init__()
        self.xdma_driver = xdma_driver

    def run(self):
        """线程主函数 - 单次执行模式，匹配C++版本"""
        try:
            # 处理中断信号
            if self.xdma_driver:
                self.xdma_driver.irq0()

            # 发送信号触发NMS处理
            self.sig_get_nms.emit()

        except Exception as e:
            print(f"EventThread错误: {e}")


class EventThread1(QThread):
    """事件线程1 - 对应C++的event_thread_1"""

    # 定义信号
    sig_get_img = Signal()

    def __init__(self, xdma_driver):
        super().__init__()
        self.xdma_driver = xdma_driver

    def run(self):
        """线程主函数 - 单次执行模式，匹配C++版本"""
        try:
            # 处理中断信号
            if self.xdma_driver:
                self.xdma_driver.irq1()

            # 发送信号触发图像获取
            self.sig_get_img.emit()

        except Exception as e:
            print(f"EventThread1错误: {e}")


class EventThread2(QThread):
    """事件线程2 - 对应C++的event_thread_2"""

    # 定义信号
    sig_get_img_1 = Signal()

    def __init__(self, xdma_driver):
        super().__init__()
        self.xdma_driver = xdma_driver

    def run(self):
        """线程主函数 - 单次执行模式，匹配C++版本"""
        try:
            # 处理中断信号
            if self.xdma_driver:
                self.xdma_driver.irq2()

            # 发送信号触发图像获取1
            self.sig_get_img_1.emit()

        except Exception as e:
            print(f"EventThread2错误: {e}")


class LoadImageThread(QThread):
    """图像加载线程 - 对应C++的load_img_thread"""

    def __init__(self, send_image):
        super().__init__()
        self.send_image = send_image

    def run(self):
        """线程主函数 - 单次执行模式，匹配C++版本"""
        try:
            # 检查图像队列
            img_count = self.send_image.get_img_cnt()

            if img_count < 10:  # 如果图像数量少于10
                # 推送图像到处理队列
                self.send_image.push_img()

        except Exception as e:
            print(f"LoadImageThread错误: {e}")


class StartCalcThread(QThread):
    """启动计算线程 - 对应C++的start_calc_thread"""

    def __init__(self, xdma_driver, send_image):
        super().__init__()
        self.xdma_driver = xdma_driver
        self.send_image = send_image

    def run(self):
        """线程主函数 - 单次执行模式，匹配C++版本"""
        try:
            # 等待图像队列有图像
            while self.send_image.get_img_cnt() <= 0:
                time.sleep(0.001)  # 1ms

            # 从队列弹出图像
            if self.send_image.pop_img():
                # 获取处理后的图像
                if self.send_image.img4 is not None and self.xdma_driver:
                    # 将图像数据发送到FPGA
                    image_data = self.send_image.img4.data

                    # 写入图像数据到FPGA地址0x10000000
                    self.xdma_driver.write_data(0x10000000, image_data)

                    # 发送启动计算命令
                    start_data = 1
                    self.xdma_driver.write_user_register(0xc, start_data)

        except Exception as e:
            print(f"StartCalcThread错误: {e}")


def test_threads():
    """测试线程功能"""
    print("测试线程系统...")

    # 这里需要实际的硬件驱动进行完整测试
    # 暂时只测试线程创建
    print("线程系统测试完成")


if __name__ == "__main__":
    test_threads()
